<?php

namespace app\common\model\food;

use Endroid\QrCode\QrCode as CodeMode;
use Endroid\QrCode\Writer\PngWriter;
use hema\alipay\Driver as Alipay;
use hema\wechat\Driver as Wechat;
use hema\wechat\Map;
use think\facade\Db;

/**
 * 门店模型
 */
class Shop extends BaseModel
{
    // 定义表名
    protected $name = 'food_shop';
    // 定义主键
    protected $pk = 'shop_id';
    // 追加字段
    protected $append = [
        'qrcode',
        'wifi',
        'paybill'
    ];

    /**
     * 获取门店码
     */
    public function getQrcodeAttr($value, $data)
    {
        $qrcode = [
            'h5' => '',
            'weixin' => '',
            'alipay' => '',
            'qrcode' => '',
        ];
        //生成存储路径
        if (!file_exists('./temp/food')) {
            mkdir('./temp/food', 0777, true);
        }
        //生成微信小程序码
        $wechat_path = '/temp/food/wechat-shop-' . $data['shop_id'] . '.png';
        if (!is_file('.' . $wechat_path)) {
            $wx = new Wechat;
            if ($wx->getUnlimitedQRCode($data['applet_id'], $wechat_path, 'shop-' . $data['shop_id'])) {
                $qrcode['weixin'] = $wechat_path;
            }
        } else {
            $qrcode['weixin'] = $wechat_path;
        }
        //如果已经发布H5端代码
        if (is_file('./h5/food/index.html')) {
            $h5_path = '/temp/food/h5-shop-' . $data['shop_id'] . '.png';
            if (!is_file('.' . $h5_path)) {
                $writer = new PngWriter();
                $code = CodeMode::create(base_url() . 'h5/food/#/?applet_id=' . $data['applet_id'] . '&q=shop-' . $data['shop_id'])->setSize(500);
                $result = $writer->write($code);
                $result->saveToFile('.' . $h5_path);
            }
            $qrcode['h5'] = $h5_path;
        }
        //生成支付宝小程序码
        $alipay_path = '/temp/food/alipay-shop-' . $data['shop_id'] . '.png';
        if (!is_file('.' . $alipay_path)) {
            $alipay = new Alipay($data['applet_id']);
            if ($alipay->openAppQrcodeCreate('shop-' . $data['shop_id'], $alipay_path)) {
                $qrcode['alipay'] = $alipay_path;
            }
        } else {
            $qrcode['alipay'] = $alipay_path;
        }
        //生成小程序聚合码
        $qrcode_path = '/temp/food/qrcode-shop-' . $data['shop_id'] . '.png';
        if (!is_file('.' . $qrcode_path)) {
            $writer = new PngWriter();
            $code = CodeMode::create(base_url() . 'food/' . $data['applet_id'] . '/shop-' . $data['shop_id'])->setSize(500);
            $result = $writer->write($code);
            $result->saveToFile('.' . $qrcode_path);
        }
        $qrcode['qrcode'] = $qrcode_path;
        return $qrcode;
    }

    /**
     * 获取买单码
     */
    public function getPaybillAttr($value, $data)
    {
        $qrcode = [
            'h5' => '',
            'weixin' => '',
            'alipay' => '',
            'qrcode' => '',
        ];
        //生成存储路径
        if (!file_exists('./temp/food')) {
            mkdir('./temp/food', 0777, true);
        }
        //生成微信小程序码
        $wechat_path = '/temp/food/wechat-paybill-' . $data['shop_id'] . '.png';
        if (!is_file('.' . $wechat_path)) {
            $wx = new Wechat;
            if ($wx->getUnlimitedQRCode($data['applet_id'], $wechat_path, 'paybill-' . $data['shop_id'])) {
                $qrcode['weixin'] = $wechat_path;
            }
        } else {
            $qrcode['weixin'] = $wechat_path;
        }
        //如果已经发布H5端代码
        if (is_file('./h5/food/index.html')) {
            $h5_path = '/temp/food/h5-paybill-' . $data['shop_id'] . '.png';
            if (!is_file('.' . $h5_path)) {
                $writer = new PngWriter();
                $code = CodeMode::create(base_url() . 'h5/food/#/?applet_id=' . $data['applet_id'] . '&q=paybill-' . $data['shop_id'])->setSize(500);
                $result = $writer->write($code);
                $result->saveToFile('.' . $h5_path);
            }
            $qrcode['h5'] = $h5_path;
        }
        //生成支付宝小程序码
        $alipay_path = '/temp/food/alipay-paybill-' . $data['shop_id'] . '.png';
        if (!is_file('.' . $alipay_path)) {
            $alipay = new Alipay($data['applet_id']);
            if ($alipay->openAppQrcodeCreate('paybill-' . $data['shop_id'], $alipay_path)) {
                $qrcode['alipay'] = $alipay_path;
            }
        } else {
            $qrcode['alipay'] = $alipay_path;
        }
        //生成小程序聚合码
        $qrcode_path = '/temp/food/qrcode-paybill-' . $data['shop_id'] . '.png';
        if (!is_file('.' . $qrcode_path)) {
            $writer = new PngWriter();
            $code = CodeMode::create(base_url() . 'food/' . $data['applet_id'] . '/paybill-' . $data['shop_id'])->setSize(500);
            $result = $writer->write($code);
            $result->saveToFile('.' . $qrcode_path);
        }
        $qrcode['qrcode'] = $qrcode_path;
        return $qrcode;
    }

    /**
     * 获取WIFI码
     */
    public function getWifiAttr($value, $data)
    {
        $qrcode = [
            'h5' => '',
            'weixin' => '',
            'alipay' => '',
            'qrcode' => '',
        ];
        //生成存储路径
        if (!file_exists('./temp/food')) {
            mkdir('./temp/food', 0777, true);
        }
        //生成微信小程序码
        $wechat_path = '/temp/food/wechat-wifi-' . $data['shop_id'] . '.png';
        if (!is_file('.' . $wechat_path)) {
            $wx = new Wechat;
            if ($wx->getUnlimitedQRCode($data['applet_id'], $wechat_path, 'wifi-' . $data['shop_id'])) {
                $qrcode['weixin'] = $wechat_path;
            }
        } else {
            $qrcode['weixin'] = $wechat_path;
        }
        //如果已经发布H5端代码
        if (is_file('./h5/food/index.html')) {
            $h5_path = '/temp/food/h5-wifi-' . $data['shop_id'] . '.png';
            if (!is_file('.' . $h5_path)) {
                $writer = new PngWriter();
                $code = CodeMode::create(base_url() . 'h5/food/#/?applet_id=' . $data['applet_id'] . '&q=wifi-' . $data['shop_id'])->setSize(500);
                $result = $writer->write($code);
                $result->saveToFile('.' . $h5_path);
            }
            $qrcode['h5'] = $h5_path;
        }
        //生成支付宝小程序码
        $alipay_path = '/temp/food/alipay-wifi-' . $data['shop_id'] . '.png';
        if (!is_file('.' . $alipay_path)) {
            $alipay = new Alipay($data['applet_id']);
            if ($alipay->openAppQrcodeCreate('wifi-' . $data['shop_id'], $alipay_path)) {
                $qrcode['alipay'] = $alipay_path;
            }
        } else {
            $qrcode['alipay'] = $alipay_path;
        }
        //生成小程序聚合码
        $qrcode_path = '/temp/food/qrcode-wifi-' . $data['shop_id'] . '.png';
        if (!is_file('.' . $qrcode_path)) {
            $writer = new PngWriter();
            $code = CodeMode::create(base_url() . 'food/' . $data['applet_id'] . '/wifi-' . $data['shop_id'])->setSize(500);
            $result = $writer->write($code);
            $result->saveToFile('.' . $qrcode_path);
        }
        $qrcode['qrcode'] = $qrcode_path;
        return $qrcode;
    }

    /**
     * 格式化页面数据（读取的时候对数据转换）
     */
    public function getFoodModeAttr($value)
    {
        $value = json_decode($value, true);
        $tab = [];
        $tmp = [
            10 => [
                'text' => '堂食',
                'value' => '10',
                'status' => '0'
            ],
            20 => [
                'text' => '外卖',
                'value' => '20',
                'status' => '0'
            ],
            30 => [
                'text' => '自取',
                'value' => '30',
                'status' => '0'
            ]
        ];
        foreach ($value as $item) {
            $tmp[$item]['status'] = '1';
            $tab[] = $tmp[$item];
        }
        return [
            'tab' => $tab, //小程序端选项卡
            'value' => $tmp
        ];
    }

    /**
     * 自动转换data为json格式(修改器，保存de时候操作)
     */
    public function setFoodModeAttr($value)
    {
        return json_encode($value);
    }

    /**
     * 门店状态
     */
    public function getStatusAttr($value, $data)
    {
        $value2 = $value;
        $status = ['歇业中', '营业中'];
        if ($value == 1) {
            $time = explode('-', $data['shop_hours']);
            $start_time = trim($time[0]);
            $end_time = trim($time[1]);
            //判断起始时间和结束时间是否一致，如一致为24小时营业
            if ($start_time != $end_time) {
                $time = time();
                $now = date('Y-m-d', $time);
                $start = strtotime($now . ' ' . $start_time . ':00');
                $end = strtotime($now . ' ' . $end_time . ':00');
                //判断是否不再营业时间
                if (!($start < $time and $end > $time)) {
                    $value = 0;
                }
            }
        }
        return ['text' => $status[$value], 'value' => $value, 'status' => $value2];
    }

    /**
     * 是否开启自动配送
     */
    public function getIsDeliveryAttr($value)
    {
        $status = ['关闭', '开启'];
        return ['text' => $status[$value], 'value' => $value];
    }

    /**
     * 是否开启骑手自动抢单
     */
    public function getIsGrabAttr($value)
    {
        $status = ['关闭', '开启'];
        return ['text' => $status[$value], 'value' => $value];
    }

    /**
     * 是否开启自动接单
     */
    public function getIsOrderAttr($value)
    {
        $status = ['关闭', '开启'];
        return ['text' => $status[$value], 'value' => $value];
    }

    /**
     * 是否开启自动配送
     */
    public function getOutShowAttr($value)
    {
        $status = ['隐藏', '显示'];
        return ['text' => $status[$value], 'value' => $value];
    }

    /**
     * 获取列表
     * @param  [type] $district 区域
     * @param  [type] $location 位置坐标
     * @param  [type] $type 类型 0=所有，10=堂食，20=外卖，30=打包，80=订桌，90排号
     * @param  [type] $sortType 门店排序 all=所有 range=距离最近 sales=销量最高 score=评分最高
     */
    public function getList($page = true, $page_n = 15, string $location = '', $shop_id = 0)
    {
        $filter = [];
        $shop_id > 0 && $filter['shop_id'] = $shop_id;
        // 执行查询
        if ($page) {
            $list = $this->where($filter)->order(['sort' => 'asc'])->paginate(['list_rows' => $page_n, 'query' => request()->param()]);
        } else {
            $list = $this->where($filter)->order(['sort' => 'asc'])->select()->toArray();
        }
        //是否计算距离
        if (!empty($location)) {
            $to = $this->order(['sort' => 'asc'])->column('coordinate');
            $to = implode(';', $to);
            $map = new Map;
            if ($result = $map->getDistance($location, $to)) {
                for ($n = 0; $n < sizeof($list); $n++) {
                    $distance = $result[$n]['distance'];
                    if (self::$applet_id > 0) {
                        //获取派送设置
                        $delivery = Setting::getItem('delivery');
                        $list[$n]['range'] = 0; //1为超出派送范围
                        if ($delivery['delivery_range'] < $distance) {
                            $list[$n]['range'] = 1; //1为超出派送范围
                        }
                    }
                    if ($distance >= 1000) {
                        $location = sprintf("%.2f", $distance / 1000) . 'km';
                    } else {
                        $location = $distance . 'm';
                    }
                    $list[$n]['distance'] = $distance;
                    $list[$n]['location'] = $location;
                }
                $list = arr_sort($list, 'distance', 'asc');
            } else {
                for ($n = 0; $n < sizeof($list); $n++) {
                    $list[$n]['location'] = '未知距离';
                    $list[$n]['distance'] = 0;
                }
            }
        }
        return $list;
    }

    /**
     * 获取详情
     */
    public static function detail($shop_id = 0, string $location = '')
    {
        if ($shop_id > 0) {
            $detail = self::find($shop_id);
            if (!empty($location)) {
                $map = new Map;
                if (!$result = $map->getDistance($location, $detail['coordinate'])) {
                    $detail['location'] = '未知距离';
                    $detail['distance'] = 0;
                } else {
                    $distance = $result[0]['distance'];
                    if (self::$applet_id > 0) {
                        //获取派送设置
                        $delivery = Setting::getItem('delivery');
                        $detail['range'] = 0; //1为超出派送范围
                        if ($delivery['delivery_range'] < $distance) {
                            $detail['range'] = 1; //1为超出派送范围
                        }
                    }
                    if ($distance >= 1000) {
                        $location = sprintf("%.2f", $distance / 1000) . 'km';
                    } else {
                        $location = $distance . 'm';
                    }
                    $detail['distance'] = $distance;
                    $detail['location'] = $location;
                }
            }
            return $detail;
        } else {
            $list = self::order(['sort' => 'asc'])->select()->toArray();
            //是否计算距离
            if (!empty($location)) {
                $to = self::order(['sort' => 'asc'])->column('coordinate');
                $to = implode(';', $to);
                $map = new Map;
                if ($result = $map->getDistance($location, $to)) {
                    for ($n = 0; $n < sizeof($list); $n++) {
                        $distance = $result[$n]['distance'];
                        if (self::$applet_id > 0) {
                            //获取派送设置
                            $delivery = Setting::getItem('delivery');
                            $list[$n]['range'] = 0; //1为超出派送范围
                            if ($delivery['delivery_range'] < $distance) {
                                $list[$n]['range'] = 1; //1为超出派送范围
                            }
                        }
                        if ($distance >= 1000) {
                            $location = sprintf("%.2f", $distance / 1000) . 'km';
                        } else {
                            $location = $distance . 'm';
                        }
                        $list[$n]['distance'] = $distance;
                        $list[$n]['location'] = $location;
                    }
                    $list = arr_sort($list, 'distance', 'asc');
                } else {
                    $list[0]['location'] = '未知距离';
                    $list[0]['distance'] = 0;
                }
            }
            return $list[0];
        }
    }

    /**
     * 获取详情
     */
    public static function getShop()
    {
        return self::order(['shop_id' => 'desc'])->find();
    }

    /**
     * 添加
     */
    public function add(array $data)
    {
        if (!isset($data['logo']) or empty($data['logo'])) {
            $this->error = '请上传门店图标';
            return false;
        }
        $map = new Map;
        if (!$location = $map->getLocation($data['coordinate'])) {
            $this->error = $map->getError();
            return false;
        }
        $data['province'] = $location['province'];
        $data['city'] = $location['city'];
        $data['district'] = $location['district'];
        $data['poi_id'] = $location['poi_id'];
        $data['applet_id'] = self::$applet_id;
        return $this->save($data);
    }


    /**
     * 编辑
     */
    public function edit(array $data)
    {
        if (!isset($data['logo']) or empty($data['logo'])) {
            $this->error = '请上传门店图标';
            return false;
        }
        $map = new Map;
        if (!$location = $map->getLocation($data['coordinate'])) {
            $this->error = $map->getError();
            return false;
        }
        $data['province'] = $location['province'];
        $data['city'] = $location['city'];
        $data['district'] = $location['district'];
        $data['poi_id'] = $location['poi_id'];
        return $this->save($data);
    }

    /**
     * 删除门店
     * $clear_all 是否全部清除
     */
    public function remove($shop_id)
    {
        if ($this->count() == 1) {
            $this->error = '至少保留一个门店';
            return false;
        }
        $filter['shop_id'] = $shop_id;
        // 开启事务
        Db::startTrans();
        try {
            $this->withoutGlobalScope()->where($filter)->delete();
            Device::withoutGlobalScope()->where($filter)->delete();
            CouponLog::withoutGlobalScope()->where($filter)->delete();
            CouponUser::withoutGlobalScope()->where($filter)->delete();
            Pact::withoutGlobalScope()->where($filter)->delete();
            Comment::withoutGlobalScope()->where($filter)->delete();
            Record::withoutGlobalScope()->where($filter)->delete();
            Table::withoutGlobalScope()->where($filter)->delete();
            ShopClerk::withoutGlobalScope()->where($filter)->delete();
            Category::withoutGlobalScope()->where($filter)->delete();
            //清除商品记录
            $goodsId = (new Goods)->withoutGlobalScope()->where($filter)->column('goods_id');
            for ($n = 0; $n < sizeof($goodsId); $n++) {
                (new Goods)->remove($goodsId[$n]);
            }
            //清除订单记录
            $orderId = (new Order)->withoutGlobalScope()->where($filter)->column('order_id');
            for ($n = 0; $n < sizeof($orderId); $n++) {
                (new Order)->remove($orderId[$n]);
            }
            Db::commit();
            return true;
        } catch (\Exception $e) {
            Db::rollback();
        }
        return false;
    }

    /**
     * 新增默认门店
     */
    public function insertDefault($applet_id, $data)
    {
        // 开启事务
        Db::startTrans();
        try {
            // 添加默认门店
            $this->save([
                'shop_name' => $data['shop_name'],
                'linkman' => $data['linkman'],
                'shop_hours' => '08:00 - 21:00',
                'phone' => $data['phone'],
                'applet_id' => $applet_id,
            ]);
            // 新增默认店长
            $clerk = new ShopClerk;
            $clerk->insertDefault($this->shop_id, $data, $applet_id);
            Db::commit();
            return true;
        } catch (\Exception $e) {
            Db::rollback();
        }
        return false;
    }

    /**
     * 获取所有 - api组件接口
     */
    public static function getAll($location = '')
    {
        $filter['status'] = 1;
        $sort = ['sort', 'shop_id' => 'desc'];
        $list = self::where($filter)->order($sort)->select();
        //是否计算距离
        if ($location) {
            for ($n = 0; $n < sizeof($list); $n++) {
                $result = getDistance($location, $list[$n]['coordinate']);
                if ($result) {
                    $distance = $result[0]['distance'];//获取距离计算结果
                    if (self::$applet_id > 0) {
                        //获取派送设置
                        $delivery = (new Setting)->getItem('delivery');
                        $list[$n]['range'] = 0; //1为超出派送范围
                        if ($delivery['delivery_range'] < $distance) {
                            $list[$n]['range'] = 1; //1为超出派送范围
                        }
                    }
                    $list[$n]['minute'] = round($result[0]['distance'] / 100);
                    if ($distance >= 1000) {
                        $distance = sprintf("%.2f", $result[0]['distance'] / 1000) . 'km';
                    } else {
                        $distance = $result[0]['distance'] . 'm';
                    }
                    $list[$n]['location'] = $distance;
                } else {
                    $list[$n]['location'] = '未知距离';
                }
            }
        }
        return $list;
    }

    public function getExitShop($shopId)
    {
        return $this->where('shop_id', $shopId)->find();
    }
}